import Vue from 'vue'
import Router from 'vue-router'
import LoginPage from './views/login-page'
import PersonalCenter from './views/personal-center'

import QuestionStatistics from './views/question-statistics'
import QuestionStatisticsAuthor from './views/question-statistics-author'
import QuestionAll from './views/question-all'
import QuestionQuery from './views/question-query'
import QuestionMine from './views/question-mine'
import QuestionShow from './views/question-show'
import QuestionCreate from './views/question-create'
import QuestionCreateIndex from './views/question-create-index'
import QuestionCreatePreview from './views/question-create-preview'
import QuestionEdit from './views/question-edit'
import QuestionEditImage from './views/question-edit-image'

import ExamAll from './views/exam-all'
import ExamIndex from './views/exam-index'
import ExamQuestion from './views/exam-question'

import CheckAll from './views/check-all'
import CheckIndex from './views/check-index'
import CheckQuestion from './views/check-question'
import CheckReview from './views/check-review'

import MessageBoard from './views/message-board'
import MessageNotice from './views/message-notice'
import MessagePrivate from './views/message-private'
import MessagePrivateChat from './views/message-private-chat'

import UserManagement from './views/user-management'

import TypeManagement from './views/type-management'

import NotFound from './views/not-found'

import store from '@/store'
import Toast from 'muse-ui-toast'
import Loading from 'muse-ui-loading'

Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: '/login',
      name: 'login-page',
      component: LoginPage,
      meta: {
        layout: 'full'
      }
    },
    {
      path: '/personal',
      name: 'personal-center',
      component: PersonalCenter,
      meta: {
        appbar: 'pc' // true false 'pc' 'mobile' 默认为true
      }
    },
    {
      path: '/questions/statistics',
      name: 'question-statistics',
      component: QuestionStatistics
    },
    {
      path: '/questions/statistics-author',
      name: 'question-statistics-author',
      component: QuestionStatisticsAuthor
    },
    {
      path: '/questions/all',
      name: 'question-all',
      component: QuestionAll
    },
    {
      path: '/questions/query',
      name: 'question-query',
      component: QuestionQuery
    },
    {
      path: '/questions/mine',
      name: 'question-mine',
      component: QuestionMine
    },
    {
      path: '/questions/show/:id',
      name: 'question-show',
      component: QuestionShow,
      props: route => ({ id: parseInt(route.params.id) })
    },
    {
      path: '/questions/create',
      name: 'question-create',
      component: QuestionCreate
    },
    {
      path: '/questions/create/index',
      name: 'question-create-index',
      component: QuestionCreateIndex
    },
    {
      path: '/questions/create/preview',
      name: 'question-create-preview',
      component: QuestionCreatePreview
    },
    {
      path: '/questions/edit/:id',
      name: 'question-edit',
      component: QuestionEdit,
      props: route => ({ id: parseInt(route.params.id) })
    },
    {
      path: '/questions/edit/:id/image',
      name: 'question-edit-image',
      component: QuestionEditImage,
      props: route => ({ id: parseInt(route.params.id) })
    },
    {
      path: '/exam/all',
      name: 'exam-all',
      component: ExamAll,
      meta: {
        auth: 'questions.exam'
      }
    },
    {
      path: '/exam/index',
      name: 'exam-index',
      component: ExamIndex,
      meta: {
        auth: 'questions.exam'
      }
    },
    {
      path: '/exam/question/:id',
      name: 'exam-question',
      component: ExamQuestion,
      props: route => ({ id: parseInt(route.params.id) }),
      meta: {
        auth: 'questions.exam'
      }
    },
    {
      path: '/check/all',
      name: 'check-all',
      component: CheckAll,
      meta: {
        auth: 'questions.check'
      }
    },
    {
      path: '/check/index',
      name: 'check-index',
      component: CheckIndex,
      meta: {
        auth: 'questions.check'
      }
    },
    {
      path: '/check/question/:id',
      name: 'check-question',
      component: CheckQuestion,
      props: route => ({ id: parseInt(route.params.id) }),
      meta: {
        auth: 'questions.check'
      }
    },
    {
      path: '/check/review',
      name: 'check-review',
      component: CheckReview,
      meta: {
        auth: 'questions.check'
      }
    },
    {
      path: '/messages/board',
      name: 'message-board',
      component: MessageBoard
    },
    {
      path: '/messages/notice',
      name: 'message-notice',
      component: MessageNotice
    },
    {
      path: '/messages/private',
      name: 'message-private',
      component: MessagePrivate,
      meta: {
        appbar: 'pc', // true false 'pc' 'mobile' 默认为true
        match: 'height'
      }
    },
    {
      path: '/messages/private/chat/:id',
      name: 'message-private-chat',
      props: route => ({ id: parseInt(route.params.id) }),
      component: MessagePrivateChat,
      meta: {
        appbar: 'pc' // true false 'pc' 'mobile' 默认为true
      }
    },
    {
      path: '/users/management',
      name: 'user-management',
      component: UserManagement,
      meta: {
        auth: 'users.management'
      }
    },
    {
      path: '/type-management',
      name: 'type-management',
      component: TypeManagement,
      meta: {
        auth: 'types.management'
      }
    },
    {
      path: '/',
      redirect: {
        name: 'message-notice'
      }
    },
    {
      path: '*',
      name: 'not-found',
      component: NotFound
    }
  ]
})

function wait(time) {
  return new Promise(resolve => {
    setTimeout(resolve, time)
  })
}

async function loadUntilInitialized() {
  const loading = Loading({
    text: '等待服务器响应，若加载时间过长，请尝试刷新'
  })
  for (let i = 0; ;i++) {
    if (store.getters.initializeError !== null) {
      loading.close()
      Loading({
        color: 'error',
        text: '发生错误，系统启动失败：' + store.getters.initializeError.message
      })
    }
    if (!store.getters.initializing) {
      loading.close()
      return true
    }
    await wait(1000)
  }
}

router.beforeEach((to, from, next) => {
  const pass = flag => {
    if (flag) {
      next()
    } else {
      next(false)
    }
  }
  const hasAllOfPermissions = arr => {
    for (const item of arr) {
      if (!store.getters.currentUserHasPermissionByCode(item)) {
        return false
      }
    }
    return true
  }
  const hasOneOfPermissions = arr => {
    for (const item of arr) {
      if (!store.getters.currentUserHasPermissionByCode(item)) {
        return true
      }
    }
    return false
  }
  const nextIfCan = () => {
    if (store.getters.isLogin) {
      const auth = to.meta.auth
      if (auth === undefined || auth === null) {
        pass(true)
      } else if (typeof auth === 'string') {
        pass(hasAllOfPermissions([auth]))
      } else if (auth instanceof Array) {
        pass(hasAllOfPermissions(auth))
      } else if (typeof auth === 'object' && auth.list && (auth.op === 'and' || auth.op === 'or')) {
        if (auth.op === 'and') {
          pass(hasAllOfPermissions(auth.list))
        } else {
          pass(hasOneOfPermissions(auth.list))
        }
      } else {
        console.warn('权限配置异常', auth)
        next()
      }
    } else {
      next({ name: 'login-page' })
    }
  }

  if (to.name === 'login-page') {
    next()
  } else if (to.fullPath === from.fullPath) {
    next(false)
  } else if (store.getters.initializing) {
    loadUntilInitialized().then(() => {
      nextIfCan()
    }).catch(err => {
      Toast.error(err.message)
      next({ name: 'login-page' })
    })
  } else {
    nextIfCan()
  }
})

export default router
